//
//  YSNETWORKINg.m
//  YSNetworkDemo
//
//  Created by 岳云石 on 2017/3/26.
//  Copyright © 2017年 岳云石. All rights reserved.
//

#import "YSNETWORKING.h"
#import <AFNetworking/AFNetworking.h>
#import <YYCache/YYCache.h>
#import "NSJSONSerialization+json.h"
//#import <YYModel.h>
static NSMutableArray *m_requestTasks;                // 网络任务请求
static NSDictionary *m_httpHeaders = nil;
static BOOL m_isallowInvalidCertificates = NO;
static BOOL m_isvalidatesDomainName = YES;
static NSInteger m_timeoutInterval = 10.0;
// 请求设置标签
static NSString * EtagString = @"";
static NSString * const None_Match = @"If-None-Match";
// 请求最后时间
static NSString * Last_Modified = @"";
static NSString * const Modified_Since = @"If-Modified-Since";

// 缓存的参数
YYCache *m_YYCache;
static NSString * m_Cache = @"YSCache";

static NSString * temp_downloadPath = @"";

@interface YSNETWORKING ()<NSURLSessionDelegate, NSURLSessionTaskDelegate>

@end

@implementation YSNETWORKING

+(void)cacheWithName:(NSString *)cachName
{
    m_Cache = cachName;
}
+(unsigned long long)totalCacheSize{
    
    if (m_YYCache) {
        return m_YYCache.diskCache.totalCost;
    }else
        return 0;
}
+(void)clearCaches{
    if (m_YYCache) {
        [m_YYCache.diskCache removeAllObjects];
    }
}
// 所有的请求任务
+ (NSMutableArray *)allTasks {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (m_requestTasks == nil) {
            m_requestTasks = [[NSMutableArray alloc] init];
        }
    });
    return m_requestTasks;
}
// 设置请求头
+ (void)configCommonHttpHeaders:(NSDictionary *)httpHeaders {
    m_httpHeaders = httpHeaders;
}
// 证书验证
+(void)httpsRequestAllowInvalidCertificates:(BOOL)isAllow ValidatesDomainName:(BOOL)isValidates
{
    m_isallowInvalidCertificates = isAllow;
    m_isvalidatesDomainName = isValidates;
}
+(void)requestTimeoutInterval:(NSInteger)timeoutInterval
{
    m_timeoutInterval = timeoutInterval;
}
+ (void)cancelAllRequest {
    @synchronized(self) {
        [[[self class] allTasks] enumerateObjectsUsingBlock:^(NSURLSessionTask * _Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([task isKindOfClass:[NSURLSessionTask class]]) {
                [task cancel];
            }
        }];
        [[[self class]allTasks] removeAllObjects];
    };
}
+ (void)cancelRequestWithURL:(NSString *)url {
    if (url == nil) {
        return;
    }
    
    @synchronized(self) {
        [[[self class]allTasks] enumerateObjectsUsingBlock:^(NSURLSessionTask * _Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([task isKindOfClass:[NSURLSessionTask class]]
                && [task.currentRequest.URL.absoluteString hasPrefix:url]) {
                [task cancel];
                [[[self class]allTasks] removeObject:task];
                return;
            }
        }];
    };
}
#pragma mark - Private
+ (AFHTTPSessionManager *)managerIsRequireToken:(BOOL)isrequireToken {
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer.stringEncoding = NSUTF8StringEncoding;
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    manager.requestSerializer.timeoutInterval = m_timeoutInterval;
    //加载资源中的根证书与网络请求的HTTPS证书去对比
    AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    policy.allowInvalidCertificates = m_isallowInvalidCertificates;//HTTPS不允许无效的证书
    policy.validatesDomainName = m_isvalidatesDomainName;//HTTPS验证证书的域名
    manager.securityPolicy = policy;
    if (isrequireToken) {
        for (NSString *key in m_httpHeaders.allKeys) {
            if (m_httpHeaders[key] != nil) {
                [manager.requestSerializer setValue:m_httpHeaders[key] forHTTPHeaderField:key];
            }
        }
    }
    if (EtagString.length>0) {
        [manager.requestSerializer setValue:EtagString forHTTPHeaderField:None_Match];
    }
    if (Last_Modified.length>0) {
        [manager.requestSerializer setValue:Last_Modified forHTTPHeaderField:Modified_Since];
    }
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json",
                                                                              @"application/x-javascript",
                                                                              @"text/html",
                                                                              @"text/json",
                                                                              @"text/plain",
                                                                              @"text/javascript",
                                                                              @"text/xml",
                                                                              @"image/*"]];
    // 设置允许同时最大并发数量，过大容易出问题
    manager.operationQueue.maxConcurrentOperationCount = 3;
    return manager;
}


#pragma  - mark  无缓存网络请求
+ (NSURLSessionTask *)requestWithURLFromRequestUrl:(NSString *)urlString
                                        parameters:(NSDictionary *)parameters
                                      requireToken:(BOOL)isrequireToken
                                        httpMethod:(kHttpMethod)httpMethod
                                          progress:(kDownloadProgress)progress
                                    requestSuccess:(ResponseSuccess)successBlock
                                     requestFailed:(Responsefailed)errorBlock;

{
    AFHTTPSessionManager *manager = [self managerIsRequireToken:isrequireToken];
    NSURLSessionTask *session = nil;
    
    if (httpMethod == HttpMethod_GET){
        session = [manager GET:urlString parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
            if (progress) {
                progress(downloadProgress.completedUnitCount, downloadProgress.totalUnitCount);
            }
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if ([responseObject isKindOfClass:[NSData class]]) {
                responseObject = [NSJSONSerialization objectWithJSONData:responseObject];
            }
            if (successBlock) {
                successBlock(responseObject);
            }
            [[YSNETWORKING  allTasks] removeObject:task];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [[YSNETWORKING allTasks] removeObject:task];
            NSError *codeError = [YSNETWORKING requestErrordatatask:(NSHTTPURLResponse *)task.response error:error];
            if (codeError) {
                errorBlock(codeError);
            }
        }];
        
    }else if (httpMethod == HttpMethod_POST){
        session = [manager POST:urlString parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
            if (progress) {
                progress(downloadProgress.completedUnitCount, downloadProgress.totalUnitCount);
            }
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            if ([responseObject isKindOfClass:[NSData class]]) {
                responseObject = [NSJSONSerialization objectWithJSONData:responseObject];
            }
            if (successBlock) {
                successBlock(responseObject);
            }
            [[YSNETWORKING allTasks] removeObject:task];
            
        }failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [[YSNETWORKING allTasks] removeObject:task];
            NSError *codeError = [YSNETWORKING requestErrordatatask:(NSHTTPURLResponse *)task.response error:error];
            if (codeError) {
                errorBlock(codeError);
            }
        }];
    }
    if (session) {
        [[self allTasks] addObject:session];
    }
    return session;
}

#pragma  - mark  带缓存网络请求
+ (NSURLSessionTask *)requestWithURLFromRequestUrl:(NSString *)urlString
                                        parameters:(NSDictionary *)parameters
                                      requireToken:(BOOL)isrequireToken
                                        httpMethod:(kHttpMethod)httpMethod
                                          progress:(kDownloadProgress)progress
                                        dataPolicy:(YSRequestDataPolicy)dataPolicy
                                    requestSuccess:(ResponseSuccess)successBlock
                                     requestFailed:(Responsefailed)errorBlock;
{
    NSString *cacheKey = urlString;
    if (parameters) {
        if (![NSJSONSerialization isValidJSONObject:parameters]) return nil;//参数不是json类型
        NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil];
        NSString *paramStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        cacheKey = [urlString stringByAppendingString:paramStr];
    }
    
    // 设置YYcache
    m_YYCache = [[YYCache alloc] initWithName:m_Cache];
    m_YYCache.memoryCache.shouldRemoveAllObjectsOnMemoryWarning = YES;
    m_YYCache.memoryCache.shouldRemoveAllObjectsWhenEnteringBackground = YES;
    m_YYCache.diskCache.costLimit = 100*1024*1024;
    m_YYCache.diskCache.ageLimit = 7*24*60*60;
    
    id object = [m_YYCache objectForKey:cacheKey];
    
    switch (dataPolicy) {
        case YSReturnCacheDataThenLoad: {     //先返回缓存，同时去网络请求返回刷新界面
            if (object) {
                !successBlock?:successBlock(object);
            }
            break;
        }
        case YSReloadNetDataDontSaveCache: {  ///< 直接请求网络，同时不存储缓存
            //不做处理，直接请求
            break;
        }
        default: {
            break;
        }
    }
    return [self requestMethod:httpMethod urlString:urlString parameters:parameters requireToken:isrequireToken dataPolicy:dataPolicy progress:progress cache:m_YYCache cacheKey:cacheKey success:successBlock failure:errorBlock];
    
    
}
+ (NSURLSessionDataTask *)requestMethod:(kHttpMethod)httpMethod
                              urlString:(NSString *)URLString
                             parameters:(id)parameters
                           requireToken:(BOOL)isrequireToken
                             dataPolicy:(YSRequestDataPolicy)dataPolicy
                               progress:(kDownloadProgress)progress
                                  cache:(id)cache
                               cacheKey:(NSString *)cacheKey
                                success:(ResponseSuccess)successBlock
                                failure:(Responsefailed)errorBlock
{
    
    AFHTTPSessionManager *manager = [self managerIsRequireToken:isrequireToken];
    NSURLSessionDataTask *session = nil;
    if (httpMethod == HttpMethod_GET){
        session = [manager GET:URLString parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
            if (progress) {
                progress(downloadProgress.completedUnitCount, downloadProgress.totalUnitCount);
            }
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            // 缓存策略
            [self responseCodeStateWithdata:responseObject datatask:task dataPolicy:dataPolicy localCachedata:cache cacheKey:cacheKey requestSuccess:successBlock];
            
            [[YSNETWORKING  allTasks] removeObject:task];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [[YSNETWORKING allTasks] removeObject:task];
            NSError *codeError = [YSNETWORKING requestErrordatatask:(NSHTTPURLResponse *)task.response error:error];
            if (codeError) {
                errorBlock(codeError);
            }
        }];
        
    }else if (httpMethod == HttpMethod_POST){
        session = [manager POST:URLString parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
            if (progress) {
                progress(downloadProgress.completedUnitCount, downloadProgress.totalUnitCount);
            }
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            // 缓存策略
            [self responseCodeStateWithdata:responseObject datatask:task dataPolicy:dataPolicy localCachedata:cache cacheKey:cacheKey requestSuccess:successBlock];
            
            [[YSNETWORKING allTasks] removeObject:task];
            
        }failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [[YSNETWORKING allTasks] removeObject:task];
            NSError *codeError = [YSNETWORKING requestErrordatatask:(NSHTTPURLResponse *)task.response error:error];
            if (codeError) {
                errorBlock(codeError);
            }
        }];
    }
    if (session) {
        [[self allTasks] addObject:session];
    }
    return session;
}
+ (void)responseCodeStateWithdata:(id)responseObject
                         datatask:(NSURLSessionDataTask *)task
                       dataPolicy:(YSRequestDataPolicy)dataPolicy
                   localCachedata:(id)localcache
                         cacheKey:(NSString *)cacheKey
                   requestSuccess:(ResponseSuccess)successBlock
{
    
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)task.response;
    NSLog(@"statusCode == %@", @(httpResponse.statusCode));
    // 判断响应的状态码是否是 304 Not Modified
    if (httpResponse.statusCode == 304) {
        NSLog(@"数据暂未更新--加载本地");
    }else{
        if ([responseObject isKindOfClass:[NSData class]]) {
            responseObject = [NSJSONSerialization objectWithJSONData:responseObject];
        }
        if (successBlock) {
            successBlock(responseObject);
        }
        switch (dataPolicy) {
            case YSReturnCacheDataThenLoad:{
                if (responseObject) {
                    [localcache setObject:responseObject forKey:cacheKey];//YYCache 已经做了responseObject为空处理
                }
                break;
            }
            case YSReloadNetDataDontSaveCache:
                break;
            default:
                break;
        }
    }
    Last_Modified =  httpResponse.allHeaderFields[@"Last-Modified"];
    EtagString =  httpResponse.allHeaderFields[@"Etag"];
    
}


#pragma  - mark  单张图片上传
+ (NSURLSessionTask *)uploadWithImage:(UIImage *)image
                                  url:(NSString *)urlString
                             filename:(NSString *)filename
                                 name:(NSString *)name
                             mimeType:(NSString *)mimeType
                           parameters:(NSDictionary *)parameters
                         requireToken:(BOOL)isrequireToken
                             progress:(kUploadProgress)progress
                              success:(ResponseSuccess)successBlock
                                 fail:(Responsefailed)errorBlock{
    
    AFHTTPSessionManager *manager = [self managerIsRequireToken:isrequireToken];
    
    NSURLSessionTask *session = [manager POST:urlString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        NSData *imageData = UIImageJPEGRepresentation(image, 0.8);
        NSString *imageFileName = filename;
        if (filename == nil || ![filename isKindOfClass:[NSString class]] || filename.length == 0) {
            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
            formatter.dateFormat = @"yyyyMMddHHmmss";
            NSString *str = [formatter stringFromDate:[NSDate date]];
            imageFileName = [NSString stringWithFormat:@"%@.jpg", str];
        }
        
        // 上传图片，以文件流的格式
        [formData appendPartWithFileData:imageData name:name fileName:imageFileName mimeType:mimeType];
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        if (progress) {
            progress(uploadProgress.completedUnitCount, uploadProgress.totalUnitCount);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [[YSNETWORKING allTasks] removeObject:task];
        if (responseObject) {
            NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject
                                                                     options:NSJSONReadingAllowFragments
                                                                       error:nil];
            successBlock(response);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [[YSNETWORKING allTasks] removeObject:task];
        NSError *codeError = [YSNETWORKING requestErrordatatask:(NSHTTPURLResponse *)task.response error:error];
        if (codeError) {
            errorBlock(codeError);
        }
    }];
    
    [session resume];
    if (session) {
        [[self allTasks] addObject:session];
    }
    
    return session;
}


#pragma - mark 图片批量上传
+ (NSURLSessionTask *)uploadWithImageArray:(NSArray *)imageArr
                                       url:(NSString *)urlString
                             filenameArray:(NSArray *)filenameArr
                                      name:(NSString *)name
                                  mimeType:(NSString *)mimeType
                                parameters:(NSDictionary *)parameters
                              requireToken:(BOOL)isrequireToken
                                  progress:(kUploadProgress)progress
                                   success:(ResponseSuccess)successBlock
                                      fail:(Responsefailed)errorBlock{
    
    NSURLSessionTask *session;
    
    AFHTTPSessionManager *manager = [self managerIsRequireToken:isrequireToken];
    session = [manager POST:urlString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        for(int i = 0; i<imageArr.count; i++) {
            UIImage *image = imageArr[i];
            NSData *imageData = UIImageJPEGRepresentation(image, 0.8);
            NSString *filename=filenameArr[i];
            NSString *imageFileName = filename;
            if (filename == nil || ![filename isKindOfClass:[NSString class]] || filename.length == 0) {
                NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                formatter.dateFormat = @"yyyyMMddHHmmss";
                NSString *str = [formatter stringFromDate:[NSDate date]];
                imageFileName = [NSString stringWithFormat:@"%@.jpg", str];
            }
            
            // 上传图片，以文件流的格式
            [formData appendPartWithFileData:imageData name:name fileName:imageFileName mimeType:mimeType];
            //                [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"上传url"] name:name fileName:imageFileName mimeType:mimeType error:nil];
            //                [formData appendPartWithFormData:imageData name:name];
        }
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        if (progress) {
            progress(uploadProgress.completedUnitCount, uploadProgress.totalUnitCount);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [[YSNETWORKING allTasks] removeObject:task];
        if (responseObject) {
            NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject
                                                                     options:NSJSONReadingAllowFragments
                                                                       error:nil];
            successBlock(response);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [[YSNETWORKING allTasks] removeObject:task];
        NSError *codeError = [YSNETWORKING requestErrordatatask:(NSHTTPURLResponse *)task.response error:error];
        if (codeError) {
            errorBlock(codeError);
        }
    }];
    
    [session resume];
    
    if (session) {
        [[self allTasks] addObject:session];
    }
    
    return session;
    
    
}


+ (NSURLSessionTask *)uploadWithFileWithURL:(NSString *)urlString
                                 uploadfile:(id )uploadfile
                                   filename:(NSString *)filename
                                       name:(NSString *)name
                                   mimeType:(NSString *)mimeType
                                 parameters:(NSDictionary *)parameters
                               requireToken:(BOOL)isrequireToken
                                   progress:(kUploadProgress)progress
                                    success:(ResponseSuccess)successBlock
                                       fail:(Responsefailed)errorBlock
{
    
    AFHTTPSessionManager *manager = [self managerIsRequireToken:isrequireToken];
    NSURLSessionTask *session = [manager POST:urlString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        if ([uploadfile isKindOfClass:[NSString class]]) {
            [formData appendPartWithFileURL:[NSURL fileURLWithPath:uploadfile] name:name fileName:filename mimeType:mimeType error:nil];
            
        }else if ([uploadfile isKindOfClass:[NSData class]]){
            [formData appendPartWithFileData:uploadfile name:name fileName:filename mimeType:mimeType ];
            
        }else
            return ;
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        if (progress) {
            progress(uploadProgress.completedUnitCount, uploadProgress.totalUnitCount);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [[YSNETWORKING allTasks] removeObject:task];
        if (responseObject) {
            NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject
                                                                     options:NSJSONReadingAllowFragments
                                                                       error:nil];
            successBlock(response);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [[YSNETWORKING allTasks] removeObject:task];
        NSError *codeError = [YSNETWORKING requestErrordatatask:(NSHTTPURLResponse *)task.response error:error];
        if (codeError) {
            errorBlock(codeError);
        }
    }];
    [session resume];
    
    if (session) {
        [[self allTasks] addObject:session];
    }
    
    return session;
}
+ (NSURLSessionTask *)uploadFileWithURL:(NSString *)urlString
                        uploadfileArray:(NSArray *)uploadfileArray
                          filenameArray:(NSArray *)filenameArray
                                   name:(NSString *)name
                               mimeType:(NSString *)mimeType
                             parameters:(NSDictionary *)parameters
                           requireToken:(BOOL)isrequireToken
                               progress:(kUploadProgress)progress
                                success:(ResponseSuccess)successBlock
                                   fail:(Responsefailed)errorBlock
{
    
    AFHTTPSessionManager *manager = [self managerIsRequireToken:isrequireToken];
    
    NSURLSessionTask *session = [manager POST:urlString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        if (filenameArray.count != uploadfileArray.count)  return ;
        BOOL isNotlegal = NO;
        for (NSInteger index = 0;index<filenameArray.count; index ++) {
            id  uploadfile = [uploadfileArray objectAtIndex:index];
            id  filename = [filenameArray objectAtIndex:index];
            if ([uploadfile isKindOfClass:[NSString class]]) {
                [formData appendPartWithFileURL:[NSURL fileURLWithPath:uploadfile] name:name fileName:filename mimeType:mimeType error:nil];
            }else if ([uploadfile isKindOfClass:[NSData class]]){
                [formData appendPartWithFileData:uploadfile name:name fileName:filename mimeType:mimeType ];
            }else{
                isNotlegal = YES;
                break;
            }
        }
        if (isNotlegal) return;
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        if (progress) {
            progress(uploadProgress.completedUnitCount, uploadProgress.totalUnitCount);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [[YSNETWORKING allTasks] removeObject:task];
        if (responseObject) {
            NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject
                                                                     options:NSJSONReadingAllowFragments
                                                                       error:nil];
            successBlock(response);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [[YSNETWORKING allTasks] removeObject:task];
        NSError *codeError = [YSNETWORKING requestErrordatatask:(NSHTTPURLResponse *)task.response error:error];
        if (codeError) {
            errorBlock(codeError);
        }
    }];
    [session resume];
    if (session) {
        [[self allTasks] addObject:session];
    }
    
    return session;
    
}
#pragma  - mark  本地文件上传
+ (NSURLSessionDataTask *)uploadFileWithUrl:(NSString *)urlString
                              uploadingFile:(NSString *)uploadingFile
                                   progress:(kUploadProgress)progress
                                    success:(ResponseSuccess)successBlock
                                       fail:(Responsefailed)errorBlock{
    
    AFHTTPSessionManager *manager = [self managerIsRequireToken:NO];
    NSURLSessionDataTask *session = nil;
    
    //    构造URL对象
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    session = [manager uploadTaskWithRequest:request fromFile:[NSURL URLWithString:uploadingFile] progress:^(NSProgress * _Nonnull uploadProgress) {
        if (progress) {
            progress(uploadProgress.completedUnitCount, uploadProgress.totalUnitCount);
        }
    } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        [[YSNETWORKING allTasks] removeObject:session];
        if (responseObject) {
            successBlock(responseObject);
        }
        NSError *codeError = [YSNETWORKING requestErrordatatask:(NSHTTPURLResponse *)response error:error];
        if (codeError) {
            errorBlock(codeError);
        }
    }];
    
    if (session) {
        [[self allTasks] addObject:session];
    }
    
    return session;
}


#pragma  - mark  网络文件下载
+ (NSURLSessionDownloadTask *)downloadWithUrl:(NSString *)urlString
                                 downloadfile:(NSString *)downloadfilePath
                                     progress:(kDownloadProgress)progressBlock
                                      success:(ResponseSuccess)successBlock
                                         fail:(Responsefailed)errorBlock{
    
    NSURLRequest *downloadRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    AFHTTPSessionManager *manager = [self managerIsRequireToken:NO];
    NSURLSessionDownloadTask *session = nil;
    session = [manager downloadTaskWithRequest:downloadRequest progress:^(NSProgress * _Nonnull downloadProgress) {
        if (progressBlock) {
            progressBlock(downloadProgress.completedUnitCount, downloadProgress.totalUnitCount);
        }
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        [[NSUserDefaults standardUserDefaults] setObject:[targetPath absoluteString] forKey:@"key_tmp"];
        [[NSUserDefaults standardUserDefaults] synchronize];
        if (!downloadfilePath) {
            NSURL *downloadURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
            return [downloadURL URLByAppendingPathComponent:[response suggestedFilename]];
        }else{
            return [NSURL fileURLWithPath:downloadfilePath];
        }
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        [[YSNETWORKING allTasks] removeObject:session];
        NSError *codeError = [YSNETWORKING requestErrordatatask:(NSHTTPURLResponse *)response error:error];
        if (codeError == nil) {
            if (successBlock && [filePath isKindOfClass:[NSURL class]]) {
                successBlock(filePath.absoluteString);
            }
        }else {
            errorBlock(codeError);
        }
    }];
    
    [session resume];
    if (session) {
        [[self allTasks] addObject:session];
    }
    
    return session;
    
}



+(NSError *)requestErrordatatask:(NSHTTPURLResponse *)response error:(NSError *)error
{
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    NSLog(@"statusCode == %@", @(httpResponse.statusCode));
    if (httpResponse.statusCode == -1001) {
        error = [NSError errorWithDomain:@"请求超时" code:-1001 userInfo:nil];
    }
    return error;
}

//获取已下载的文件大小
+ (unsigned long long)fileSizeForPath:(NSString *)path {
    signed long long fileSize = 0;
    NSFileManager *fileManager = [NSFileManager new]; // default is not thread safe
    if ([fileManager fileExistsAtPath:path]) {
        NSError *error = nil;
        NSDictionary *fileDict = [fileManager attributesOfItemAtPath:path error:&error];
        if (!error && fileDict) {
            fileSize = [fileDict fileSize];
        }
    }
    return fileSize;
}

@end
